package city.spring.modules.checkinfeeDetail.controller;

import city.spring.modules.checkinfeeDetail.entity.CheckinfeeDetailEntity;
import city.spring.modules.checkinfeeDetail.service.CheckinfeeDetailService;
import city.spring.modules.checkinfeeDetail.vo.CheckinfeeDetailVO;
import city.spring.modules.checkinfeeDetail.vo.PrintCheckinfeeVO;
import city.spring.modules.checkinfeeDetail.vo.PrintOldmanDepositVO;
import city.spring.modules.expense.service.ExpenseRecordService;
import city.spring.modules.oldman.vo.OldmanDepositVO;
import city.spring.utils.MyBatisUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Controller：入院收费记录
 *
 * @author 谢金婷
 * @date 2020-08-24 15:46:11
 */
@RestController
@RequestMapping("/checkinfeeDetail")
public class CheckinfeeDetailController extends ApiController {
    private final CheckinfeeDetailService checkinfeeDetailService;
    /**
     * 实体类可排序字段
     */
    private final List<SFunction<CheckinfeeDetailEntity, ?>> entityOrderFields;
    private final ExpenseRecordService expenseRecordService;

    public CheckinfeeDetailController(CheckinfeeDetailService checkinfeeDetailService, ExpenseRecordService expenseRecordService) {
        this.checkinfeeDetailService = checkinfeeDetailService;
        this.expenseRecordService = expenseRecordService;
        entityOrderFields = new ArrayList<>();
        entityOrderFields.add(CheckinfeeDetailEntity::getId);
        entityOrderFields.add(CheckinfeeDetailEntity::getConsumptionItemsId);
        entityOrderFields.add(CheckinfeeDetailEntity::getStandardPrice);
        entityOrderFields.add(CheckinfeeDetailEntity::getReceivableThisMonth);
        entityOrderFields.add(CheckinfeeDetailEntity::getRemark);
        entityOrderFields.add(CheckinfeeDetailEntity::getDateStart);
        entityOrderFields.add(CheckinfeeDetailEntity::getDateTo);
    }

    /**
     * 获取全部的 <strong>入院收费记录</strong> 列表
     */
    @GetMapping("all")
    public Object listAll(@PageableDefault Pageable pageable, CheckinfeeDetailEntity entity) {
        LambdaQueryChainWrapper<CheckinfeeDetailEntity> lambdaQuery = buildLambdaQuery(entity);
        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
        return success(lambdaQuery.list());
    }

    /**
     * 分页获取 <strong>入院收费记录</strong> 列表
     *
     * @param pageable 分页参数信息
     */
    @GetMapping
    public Object list(@PageableDefault Pageable pageable, CheckinfeeDetailVO entity) {
//        LambdaQueryChainWrapper<CheckinfeeEntity> lambdaQuery = buildLambdaQuery(entity);
//        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
//        Page<CheckinfeeEntity> page = lambdaQuery.page(MyBatisUtils.toPage(pageable, false));
//        return success(page);
        QueryWrapper<? extends CheckinfeeDetailEntity> queryWrapper = buildQuery(entity);
        return success(checkinfeeDetailService.listPage(MyBatisUtils.toPage(pageable), queryWrapper));
    }

    /**
     * 获取月度缴费明细
     *
     * @param feeid
     * @return
     */
    @GetMapping("monthPayDetail/{feeid}")
    public Object monthPayDetail(@PathVariable String feeid) {
        List<CheckinfeeDetailVO> records = checkinfeeDetailService.monthPayDetail(feeid);
        return success(records);
    }

    /**
     * 获取一个 <strong>入院收费记录</strong>
     *
     * @param id 主键ID
     */
    @GetMapping("{id}")
    public Object info(@PathVariable String id) {
//        return success(checkinfeeDetailService.getById(id));
        QueryWrapper<CheckinfeeDetailVO> wrapper = new QueryWrapper<>();
        wrapper.eq("t1.id", id);
        List<CheckinfeeDetailVO> records = checkinfeeDetailService.listPage(new Page<>(), wrapper).getRecords();
        if (records.isEmpty()) {
            return success(null);
        }
        return success(records.get(0));
    }

    /**
     * 获取押金及预存余额
     *
     * @param personId
     * @return
     */
    @GetMapping("getDepositAndBalance/{personId}")
    public Object getDepositAndBalance(@PathVariable String personId) {
        CheckinfeeDetailVO entity = checkinfeeDetailService.getDepositAndBalance(personId);
        return success(entity);
    }

    /**
     * 添加一个 <strong>入院收费记录</strong>
     *
     * @param entity 修改后的信息
     */
    @PostMapping
    public Object add(@RequestBody CheckinfeeDetailEntity entity) {
        checkinfeeDetailService.saveCheckinfee(entity);

        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.LOCATION, String.valueOf(entity.getId()));
        return new ResponseEntity<>(headers, HttpStatus.CREATED);
    }

    /**
     * 修改一个 <strong>入院收费记录</strong>
     *
     * @param id     主键ID
     * @param entity 修改后的信息
     */
    @PutMapping("{id}")
    public Object update(@PathVariable String id, @RequestBody CheckinfeeDetailEntity entity) {
        entity.setId(id);
        checkinfeeDetailService.updateCheckinfee(entity);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 删除一个 <strong>入院收费记录</strong>
     *
     * @param id 主键ID
     */
    @DeleteMapping("{id}")
    public Object delete(@PathVariable String id) {
        checkinfeeDetailService.deleteCheckinfee(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 删除多个 <strong>入院收费记录</strong>
     *
     * @param ids 主键ID列表
     */
    @DeleteMapping
    public Object deleteIds(@RequestBody List<String> ids) {
        checkinfeeDetailService.deleteCheckinfee(ids);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private LambdaQueryChainWrapper<CheckinfeeDetailEntity> buildLambdaQuery(CheckinfeeDetailEntity entity) {
        LambdaQueryChainWrapper<CheckinfeeDetailEntity> lambdaQuery = checkinfeeDetailService.lambdaQuery();
        lambdaQuery.eq(StringUtils.isNotBlank(entity.getId()), CheckinfeeDetailEntity::getId, entity.getId());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getConsumptionItemsId()), CheckinfeeDetailEntity::getConsumptionItemsId, entity.getConsumptionItemsId());
        lambdaQuery.eq(entity.getStandardPrice() != null, CheckinfeeDetailEntity::getStandardPrice, entity.getStandardPrice());
        lambdaQuery.eq(entity.getReceivableThisMonth() != null, CheckinfeeDetailEntity::getReceivableThisMonth, entity.getReceivableThisMonth());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getRemark()), CheckinfeeDetailEntity::getRemark, entity.getRemark());
        return lambdaQuery;
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private QueryWrapper<CheckinfeeDetailEntity> buildQuery(CheckinfeeDetailVO entity) {
        QueryWrapper<CheckinfeeDetailEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(entity.getId()), "t1.id", entity.getId());
        wrapper.eq(StringUtils.isNotBlank(entity.getOldmanId()), "t1.oldman_id", entity.getOldmanId());
        wrapper.eq(StringUtils.isNotBlank(entity.getOldmanName()), "t2.oldman_name", entity.getOldmanName());
        wrapper.like(StringUtils.isNotBlank(entity.getConsumptionItemsId()), "t1.consumption_items_id", entity.getConsumptionItemsId());
        wrapper.eq(entity.getStandardPrice() != null, "t1.standard_price", entity.getStandardPrice());
        wrapper.eq(entity.getReceivableThisMonth() != null, "t1.receivable_this_month", entity.getReceivableThisMonth());
        wrapper.eq(entity.getStatus() != null, "t1.status", entity.getStatus());
        wrapper.like(StringUtils.isNotBlank(entity.getRemark()), "t1.remark", entity.getRemark());
        return wrapper;
    }

    /**
     * 获取打印收据凭证的数据信息
     *
     * @param ids 消费记录ID列表信息
     * @return json
     */
    @PostMapping("getPrintReceiptInfo")
    public Object getPrintReceiptInfo(@RequestBody List<String> ids) {
        PrintCheckinfeeVO data = checkinfeeDetailService.getPrintReceiptInfo(ids);
        return success(data);
    }


    /**
     * 根据老人id和收费标记获取该老人的入院收费的入院固定费用
     *
     * @param oldmanId
     * @param mark
     * @return
     */
    @GetMapping("/getFixedcostsByOldmanIdAndMark")
    public Object getFixedcostsByOldmanIdAndMark(String checkinfeeId, String oldmanId, String mark) {
        return success(checkinfeeDetailService.getFixedcostsByOldmanIdAndMark(checkinfeeId, oldmanId, mark));
    }

    /**
     * 根据老人id和收费标记获取该老人的入院收费的押金
     *
     * @param oldmanId
     * @param mark
     * @return
     */
    @GetMapping("/getDepositByOldmanIdAndMark")
    public Object getDepositByOldmanIdAndMark(String checkinfeeId, String oldmanId, String mark) {
        return success(checkinfeeDetailService.getDepositByOldmanIdAndMark(checkinfeeId, oldmanId, mark));
    }

    /**
     * 根据老人id和收费标记获取该老人的入院收费的餐饮费
     *
     * @param checkinfeeId
     * @param oldmanId
     * @param mark
     * @return
     */
    @GetMapping("/getDiningfeeByOldmanIdAndMark")
    public Object getDiningfeeByOldmanIdAndMark(String checkinfeeId, String oldmanId, String mark) {
        return success(checkinfeeDetailService.getDiningfeeByOldmanIdAndMark(checkinfeeId, oldmanId, mark));
    }

    /**
     * 根据老人id和收费标记获取该老人的入院收费的水电费
     *
     * @param checkinfeeId
     * @param oldmanId
     * @param mark
     * @return
     */
    @GetMapping("/getUtilitybillByOldmanIdAndMark")
    public Object getUtilitybillByOldmanIdAndMark(String checkinfeeId, String oldmanId, String mark) {
        return success(checkinfeeDetailService.getUtilitybillByOldmanIdAndMark(checkinfeeId, oldmanId, mark));
    }

    /**
     * 根据老人id和收费标记获取该老人的入院收费的入住月收费用类别
     *
     * @param oldmanId
     * @param mark
     * @return
     */
    @GetMapping("/getMfeeByOldmanIdAndMark")
    public Object getMfeeByOldmanIdAndMark(String checkinfeeId, String oldmanId, String mark) {
        return success(checkinfeeDetailService.getMfeeByOldmanIdAndMark(checkinfeeId, oldmanId, mark));
    }

    /**
     * 根据老人id和收费标记获取该老人的入院收费的追加月费用
     *
     * @param checkinfeeId
     * @param oldmanId
     * @param mark
     * @return
     */
    @GetMapping("/getMonthlyfeeByOldmanIdAndMark")
    public Object getMonthlyfeeByOldmanIdAndMark(String checkinfeeId, String oldmanId, String mark) {
        return success(checkinfeeDetailService.getMonthlyfeeByOldmanIdAndMark(checkinfeeId, oldmanId, mark));
    }


    /**
     * 计算入院收费本月应收费用总和
     *
     * @param checkinfeeId
     * @param oldmanId
     * @param mark
     * @return
     */
    @GetMapping("/getSumReceivablethisMonth")
    public BigDecimal getSumReceivablethisMonth(String checkinfeeId, String oldmanId, String mark) {
        return checkinfeeDetailService.getSumReceivablethisMonth(checkinfeeId, oldmanId, mark);
    }

    /**
     * 根据老人id获取该老人的入院收费的餐饮费
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("getDiningfeeByOldmanId/{oldmanId}")
    public Object getDiningfeeByOldmanId(@PathVariable String oldmanId) {
        return success(checkinfeeDetailService.getDiningfeeByOldmanId(oldmanId));
    }

    /**
     * 根据老人id获取该老人的入院收费的水电费
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("getUtilitybillByOldmanId/{oldmanId}")
    public Object getUtilitybillByOldmanId(@PathVariable String oldmanId) {
        return success(checkinfeeDetailService.getUtilitybillByOldmanId(oldmanId));
    }

    /**
     * 根据老人id获取该老人的入院收费的押金
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("getDepositByOldmanId/{oldmanId}")
    public Object getDepositByOldmanId(@PathVariable String oldmanId) {
        return success(checkinfeeDetailService.getDepositByOldmanId(oldmanId));
    }

    /**
     * 根据老人id获取该老人的入院收费的其他费用
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("getFixedcostsByOldmanId/{oldmanId}")
    public Object getFixedcostsByOldmanId(@PathVariable String oldmanId) {
        return success(checkinfeeDetailService.getFixedcostsByOldmanId(oldmanId));
    }

    /**
     * 根据老人id获取该老人的入院收费的追加月费用
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("getMonthlyfeeByOldmanId/{oldmanId}")
    public Object getMonthlyfeeByOldmanId(@PathVariable String oldmanId) {
        return success(checkinfeeDetailService.getMonthlyfeeByOldmanId(oldmanId));
    }

    /**
     * 月度缴费 获取应缴费用信息 （床位、护理、餐饮、水电、定制护理费）
     */
    @GetMapping("monthPayInfo/{checkfeeid}")
    public Object monthPayInfo(@PathVariable String checkfeeid) {
        List<CheckinfeeDetailVO> records = checkinfeeDetailService.monthPayInfo(checkfeeid);
        return success(records);
    }

    /**
     * 月度缴费 获取应缴费用信息 （床位、护理、餐饮、水电、定制护理费）
     */
    @GetMapping("monthPayInfoOne/{checkfeeid}/{typenum}")
    public Object monthPayInfoOne(@PathVariable String checkfeeid, @PathVariable Integer typenum) {
        CheckinfeeDetailVO records = checkinfeeDetailService.monthPayInfoOne(checkfeeid, typenum);
        return success(records);
    }

    /**
     * 查找入院缴费的护理级别费用
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("getAttendance/{oldmanId}")
    public Object getAttendance(@PathVariable String oldmanId) {
        return success(checkinfeeDetailService.getAttendance(oldmanId));
    }

    /**
     * 查找入院缴费的定制护理费
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("getPrivatecustomizationFee/{oldmanId}")
    public Object getPrivatecustomizationFee(@PathVariable String oldmanId) {
        return success(checkinfeeDetailService.getPrivatecustomizationFee(oldmanId));
    }

    /**
     * 查找入院缴费的床位费用
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("getBed/{oldmanId}")
    public Object getBed(@PathVariable String oldmanId) {
        return success(checkinfeeDetailService.getBed(oldmanId));
    }


    /**
     * 查找入院缴费的餐饮费
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("getDiningfee/{oldmanId}")
    public Object getDiningfee(@PathVariable String oldmanId) {
        return success(checkinfeeDetailService.getDiningfee(oldmanId));
    }

    /**
     * 查找入院缴费的水电费
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("getUtilitybill/{oldmanId}")
    public Object getUtilitybill(@PathVariable String oldmanId) {
        return success(checkinfeeDetailService.getUtilitybill(oldmanId));
    }

    /**
     * 查找入院缴费的追加月费用记录
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("getMonthlyfee/{oldmanId}")
    public Object getMonthlyfee(@PathVariable String oldmanId) {
        return success(checkinfeeDetailService.getMonthlyfee(oldmanId));
    }

    /**
     * 查询所有的押金
     *
     * @param pageable
     * @param entity
     * @return
     */
    @GetMapping("/oldmanDepositList")
    public Object oldmanDepositList(@PageableDefault Pageable pageable, OldmanDepositVO entity) {

        QueryWrapper<? extends CheckinfeeDetailEntity> queryWrapper = oldmanDepositListbuildQuery(entity);
        return success(checkinfeeDetailService.oldmanDepositListPage(MyBatisUtils.toPage(pageable), queryWrapper));
    }

    @GetMapping("oldmanDepositList/{id}")
    public Object oldmanDepositList(@PathVariable String id) {

        QueryWrapper<OldmanDepositVO> wrapper = new QueryWrapper<>();
        wrapper.eq("t1.id", id);
        List<OldmanDepositVO> records = checkinfeeDetailService.oldmanDepositListPage(new Page<>(), wrapper).getRecords();
        if (records.isEmpty()) {
            return success(null);
        }
        return success(records.get(0));
    }

    private QueryWrapper<CheckinfeeDetailEntity> oldmanDepositListbuildQuery(OldmanDepositVO entity) {
        QueryWrapper<CheckinfeeDetailEntity> wrapper = new QueryWrapper<>();
        wrapper.like(entity.getId() != null, "t1.id", entity.getId());
        wrapper.like(StringUtils.isNotBlank(entity.getOldmanId()), "cd.oldman_id", entity.getOldmanId());
        wrapper.like(StringUtils.isNotBlank(entity.getOldmanName()), "oi.oldman_name", entity.getOldmanName());
        return wrapper;
    }

    /**
     * 获取打印收据凭证的数据信息 打印押金
     *
     * @param ids 消费记录ID列表信息
     * @return json
     */
    @PostMapping("getPrintOldmanDeposit")
    public Object getPrintOldmanDeposit(@RequestBody List<String> ids) {
        PrintOldmanDepositVO data = checkinfeeDetailService.getPrintOldmanDeposit(ids);
        return success(data);
    }

    /**
     * 退住结算：账单情况：罗列截至退住日期的需要交费的应付账单
     *
     * @param personId
     * @return
     */
    @GetMapping("settlement/billToLeaveDate/{personId}/{leaveDate}/{monthEnd}")
    public Object billToLeaveDate(@PathVariable String personId, @PathVariable Date leaveDate, @PathVariable Date monthEnd) {
        List<CheckinfeeDetailVO> records = checkinfeeDetailService.billToLeaveDate(personId, leaveDate, monthEnd);
        return success(records);
    }
}
